<template>
  <div class="game-container">
    <div class="game-header">
      <h1>僵尸围城</h1>
      <div class="game-stats">
        <div class="stat">
          <span>生命值</span>
          <div class="health-bar">
            <div class="health-fill" :style="{ width: playerHealth + '%' }"></div>
          </div>
          <span>{{ playerHealth }}/100</span>
        </div>
        <div class="stat">
          <span>分数</span>
          <span class="score">{{ score }}</span>
        </div>
        <div class="stat">
          <span>波次</span>
          <span class="wave">{{ currentWave }}</span>
        </div>
        <div class="stat">
        <span>武器</span>
        <span class="weapon">{{ weapons[currentWeapon.value]?.name || '手枪' }}</span>
      </div>
      <div class="stat">
        <span>弹药</span>
        <span class="ammo">{{ ammo }}/{{ maxAmmo }}</span>
      </div>
      </div>
    </div>

    <div class="game-area" :class="'wave-' + currentWave" @click="shoot" @mousemove="aimPlayer">
      <div class="player" :style="{ left: playerX + 'px', top: playerY + 'px' }">
        <span class="player-icon">🦸</span>
        <div class="gun" :style="{ transform: 'rotate(' + gunAngle + 'deg)' }"></div>
      </div>
      
      <div v-for="zombie in zombies" :key="zombie.id" 
           class="zombie" 
           :class="['zombie-type-' + (zombie.type || 1), { 'zombie-dead': zombie.health <= 0 }]"
           :style="{ left: zombie.x + 'px', top: zombie.y + 'px' }">
        <div class="zombie-health">
          <div class="zombie-health-bar" :style="{ width: (zombie.health / zombie.maxHealth * 100) + '%' }"></div>
        </div>
        <span class="zombie-icon">{{ zombie.type === 2 ? '👹' : zombie.type === 3 ? '👺' : '🧟‍♂️' }}</span>
      </div>

      <div v-for="bullet in bullets" :key="bullet.id" 
           class="bullet"
           :style="{ left: bullet.x + 'px', top: bullet.y + 'px', background: bullet.color || '#ffd93d' }">
      </div>

      <!-- 道具 -->
      <div v-for="item in items" :key="item.id" 
           class="item"
           :class="item.type"
           :style="{ left: item.x + 'px', top: item.y + 'px' }">
        <span>{{ 
          item.type === 'health' ? '💊' : 
          item.type === 'ammo' ? '🔫' : 
          item.weaponType === 'shotgun' ? '🎯' : '🔥'
        }}</span>
      </div>

      <div v-if="gameOver" class="game-over">
        <h2>{{ currentWave >= 5 ? '恭喜通关！' : '游戏结束' }}</h2>
        <p>最终分数: {{ score }}</p>
        <p>完成波次: {{ currentWave }}/5</p>
        <button @click="restartGame" class="restart-btn">重新开始</button>
      </div>

      <div v-if="waveComplete" class="wave-complete">
        <h2>波次完成！</h2>
        <p>准备下一波...</p>
      </div>

      <div v-if="isPaused" class="game-over">
        <h2>游戏暂停</h2>
        <p>按 P 键或点击按钮继续游戏</p>
      </div>
    </div>

    <div class="controls">
      <button @click="reload" :disabled="isReloading || ammo === maxAmmo" class="reload-btn">
        {{ isReloading ? '装填中...' : '装填' }}
      </button>
      <button @click="startGame" v-if="!gameStarted" class="start-btn">开始游戏</button>
      <button @click="togglePause" v-if="gameStarted && !gameOver" class="reload-btn">
        {{ isPaused ? '继续游戏' : '暂停游戏' }}
      </button>
    </div>

    <div class="instructions">
      <h3>游戏说明</h3>
      <p>🖱️ 鼠标移动瞄准，点击射击</p>
      <p>🧟 消灭僵尸获得分数</p>
      <p>💊 击败僵尸有几率掉落血包、弹药和新武器</p>
      <p>🔫 武器：1手枪 2散弹枪 3连发枪</p>
      <p>🎯 散弹枪：多发子弹，近距离高伤害</p>
      <p>🔥 连发枪：射速快，适合持续输出</p>
      <p>⏸️ 暂停：按 P 键或点击暂停按钮</p>
      <p>⚡ 僵尸会越来越强，小心应对！</p>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'

// 游戏状态
const gameStarted = ref(false)
const gameOver = ref(false)
const waveComplete = ref(false)
const isPaused = ref(false)
const playerHealth = ref(100)
const playerX = ref(500)
const playerY = ref(625)
const playerVelocityX = ref(0)
const playerVelocityY = ref(0)
const gunAngle = ref(0)
const score = ref(0)
const currentWave = ref(1)
const ammo = ref(30)
const maxAmmo = ref(30)
const isReloading = ref(false)

// 游戏配置
const config = {
  zombieSpeed: 1,
  zombieHealth: 50,
  bulletSpeed: 10,
  damage: 25,
  spawnInterval: 2000,
  zombiesPerWave: 5,
  playerSpeed: 0.5,
  playerMaxSpeed: 7,
  playerFriction: 0.92,
  itemSpawnChance: 0.35, // 僵尸死亡时道具掉落概率
  itemLifetime: 10000 // 道具存在时间(毫秒)
}

// 武器系统
const weapons = {
  pistol: {
    name: '手枪',
    damage: 35,
    ammo: 12,
    maxAmmo: 12,
    fireRate: 400,
    spread: 0,
    bulletCount: 1,
    color: '#ffd93d'
  },
  shotgun: {
    name: '散弹枪',
    damage: 25,
    ammo: 8,
    maxAmmo: 8,
    fireRate: 500,
    spread: 0.3,
    bulletCount: 5,
    color: '#ff6b6b'
  },
  rifle: {
    name: '连发枪',
    damage: 30,
    ammo: 25,
    maxAmmo: 25,
    fireRate: 100,
    spread: 0.1,
    bulletCount: 1,
    color: '#4a90e2'
  }
}

// 游戏对象
const zombies = ref([])
const bullets = ref([])
const items = ref([])
const currentWeapon = ref('pistol')

// 游戏循环
let gameLoop = null
let zombieSpawnTimer = null

// 开始游戏
const startGame = () => {
  gameStarted.value = true
  ammo.value = weapons[currentWeapon.value].ammo
  maxAmmo.value = weapons[currentWeapon.value].maxAmmo
  startWave()
  gameLoop = setInterval(updateGame, 16)
}

// 重新开始
const restartGame = () => {
  gameOver.value = false
  isPaused.value = false
  playerHealth.value = 100
  score.value = 0
  currentWave.value = 1
  currentWeapon.value = 'pistol'
  ammo.value = weapons.pistol.ammo
  maxAmmo.value = weapons.pistol.maxAmmo
  zombies.value = []
  bullets.value = []
  items.value = []
  startWave()
}

// 开始新波次
const startWave = () => {
  waveComplete.value = false
  // 逐步增加僵尸数量：第1波5只，第2波8只，第3波11只，第4波14只，第5波17只
  const zombieCount = 5 + (currentWave.value - 1) * 3
  
  // 清除上一波的僵尸
  zombies.value = []
  
  // 生成新波次的僵尸，每波生成速度加快
  const spawnDelay = Math.max(800, config.spawnInterval - (currentWave.value - 1) * 200)
  for (let i = 0; i < zombieCount; i++) {
    setTimeout(() => {
      spawnZombie()
    }, i * spawnDelay)
  }
  
  // 恢复生命和弹药
  playerHealth.value = Math.min(100, playerHealth.value + 20)
  ammo.value = maxAmmo.value
}

// 生成道具
const spawnItem = (x, y) => {
  const types = ['health', 'ammo', 'weapon']
  const type = types[Math.floor(Math.random() * types.length)]
  
  let weaponType = null
  if (type === 'weapon') {
    const weapons = ['shotgun', 'rifle']
    weaponType = weapons[Math.floor(Math.random() * weapons.length)]
  }
  
  items.value.push({
    id: Date.now() + Math.random(),
    x: x + 15, // 中心位置
    y: y + 15,
    type,
    weaponType,
    createdAt: Date.now()
  })
}

// 生成僵尸
const spawnZombie = () => {
  const side = Math.floor(Math.random() * 4)
  let x, y
  
  switch(side) {
    case 0: // 上
      x = Math.random() * 1000
      y = -30
      break
    case 1: // 右
      x = 1030
      y = Math.random() * 750
      break
    case 2: // 下
      x = Math.random() * 1000
      y = 780
      break
    case 3: // 左
      x = -30
      y = Math.random() * 750
      break
  }
  
  // 根据波次调整僵尸属性
  const healthMultiplier = 1 + (currentWave.value - 1) * 0.3
  const speedMultiplier = 1 + (currentWave.value - 1) * 0.2
  const health = Math.floor((config.zombieHealth + (currentWave.value - 1) * 20) * healthMultiplier)
  const zombieType = Math.min(3, Math.floor(currentWave.value / 2) + 1)
  
  zombies.value.push({
    id: Date.now() + Math.random(),
    x,
    y,
    health: health * (1 + (zombieType - 1) * 0.3),
    maxHealth: health * (1 + (zombieType - 1) * 0.3),
    speed: (config.zombieSpeed + (currentWave.value - 1) * 0.2) * speedMultiplier,
    type: zombieType
  })
}

// 瞄准
const aimPlayer = (event) => {
  if (!gameStarted.value || gameOver.value) return
  
  const rect = event.target.getBoundingClientRect()
  const mouseX = event.clientX - rect.left
  const mouseY = event.clientY - rect.top
  
  // 修正玩家中心点计算，与射击函数保持一致
  const playerCenterX = playerX.value + 20  // 40px宽度的一半
  const playerCenterY = playerY.value + 20  // 40px高度的一半
  
  const deltaX = mouseX - playerCenterX
  const deltaY = mouseY - playerCenterY
  
  gunAngle.value = Math.atan2(deltaY, deltaX) * 180 / Math.PI
}

// 射击
const shoot = (event) => {
  if (!gameStarted.value || gameOver.value || isReloading.value || ammo.value <= 0) return
  
  const weapon = weapons[currentWeapon.value]
  const rect = event.target.getBoundingClientRect()
  const mouseX = event.clientX - rect.left
  const mouseY = event.clientY - rect.top
  
  // 修正玩家中心点计算，考虑CSS transform偏移
  const playerCenterX = playerX.value + 20  // 40px宽度的一半
  const playerCenterY = playerY.value + 20  // 40px高度的一半
  
  const deltaX = mouseX - playerCenterX
  const deltaY = mouseY - playerCenterY
  const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY)
  
  const baseDirectionX = deltaX / distance
  const baseDirectionY = deltaY / distance
  
  // 根据武器类型生成不同数量的子弹
  for (let i = 0; i < weapon.bulletCount; i++) {
    let directionX = baseDirectionX
    let directionY = baseDirectionY
    
    // 添加散射效果
    if (weapon.spread > 0) {
      const angle = (Math.random() - 0.5) * weapon.spread * 2
      const cos = Math.cos(angle)
      const sin = Math.sin(angle)
      directionX = baseDirectionX * cos - baseDirectionY * sin
      directionY = baseDirectionX * sin + baseDirectionY * cos
    }
    
    bullets.value.push({
      id: Date.now() + Math.random() + i,
      x: playerX.value + 20,  // 与玩家中心点保持一致
      y: playerY.value + 20,  // 与玩家中心点保持一致
      dx: directionX * config.bulletSpeed,
      dy: directionY * config.bulletSpeed,
      damage: weapon.damage,
      color: weapon.color
    })
  }
  
  ammo.value--
}

// 装填
const reload = () => {
  if (isReloading.value || ammo.value === maxAmmo.value) return
  
  isReloading.value = true
  setTimeout(() => {
    ammo.value = maxAmmo.value
    isReloading.value = false
  }, 2000)
}

// 切换武器
const switchWeapon = (weaponType) => {
  if (!weapons[weaponType]) return
  
  currentWeapon.value = weaponType
  ammo.value = weapons[weaponType].ammo
  maxAmmo.value = weapons[weaponType].maxAmmo
}

// 更新游戏
const updateGame = () => {
  if (gameOver.value || isPaused.value) return
  
  // 更新玩家位置（消除卡顿的平滑移动）
  let targetVelocityX = 0
  let targetVelocityY = 0

  // 计算目标速度向量
  if (keysPressed.has('w') || keysPressed.has('arrowup')) targetVelocityY -= 1
  if (keysPressed.has('s') || keysPressed.has('arrowdown')) targetVelocityY += 1
  if (keysPressed.has('a') || keysPressed.has('arrowleft')) targetVelocityX -= 1
  if (keysPressed.has('d') || keysPressed.has('arrowright')) targetVelocityX += 1

  // 归一化对角线移动速度
  if (targetVelocityX !== 0 && targetVelocityY !== 0) {
    const magnitude = Math.sqrt(targetVelocityX * targetVelocityX + targetVelocityY * targetVelocityY)
    targetVelocityX /= magnitude
    targetVelocityY /= magnitude
  }

  // 平滑过渡到目标速度
  const acceleration = 0.8
  playerVelocityX.value += (targetVelocityX * config.playerMaxSpeed - playerVelocityX.value) * acceleration
  playerVelocityY.value += (targetVelocityY * config.playerMaxSpeed - playerVelocityY.value) * acceleration

  // 应用摩擦力（当没有输入时）
  if (targetVelocityX === 0) playerVelocityX.value *= config.playerFriction
  if (targetVelocityY === 0) playerVelocityY.value *= config.playerFriction

  // 限制最大速度
  const currentSpeed = Math.sqrt(playerVelocityX.value * playerVelocityX.value + playerVelocityY.value * playerVelocityY.value)
  if (currentSpeed > config.playerMaxSpeed) {
    playerVelocityX.value = (playerVelocityX.value / currentSpeed) * config.playerMaxSpeed
    playerVelocityY.value = (playerVelocityY.value / currentSpeed) * config.playerMaxSpeed
  }

  // 更新位置
  playerX.value = Math.max(20, Math.min(980, playerX.value + playerVelocityX.value))
  playerY.value = Math.max(20, Math.min(730, playerY.value + playerVelocityY.value))
  
  // 处理子弹碰撞（先处理碰撞，再更新僵尸位置）
  bullets.value = bullets.value.filter(bullet => {
    bullet.x += bullet.dx
    bullet.y += bullet.dy
    
    // 检查边界
    if (bullet.x < 0 || bullet.x > 1000 || bullet.y < 0 || bullet.y > 750) {
      return false
    }
    
    // 检查碰撞
    let hit = false
    zombies.value.forEach(zombie => {
      if (zombie.health > 0) {
        const distance = Math.sqrt(
          Math.pow(bullet.x - (zombie.x + 14), 2) + 
          Math.pow(bullet.y - (zombie.y + 14), 2)
        )
        
        if (distance < 20) {
          zombie.health -= bullet.damage || config.damage
          hit = true
          
          if (zombie.health <= 0) {
            score.value += 10 * currentWave.value
            
            // 僵尸死亡时有概率掉落道具
            if (Math.random() < config.itemSpawnChance) {
              spawnItem(zombie.x, zombie.y)
            }
          }
        }
      }
    })
    
    return !hit
  })
  
  // 更新僵尸（死亡僵尸立即移除，防止继续移动）
  zombies.value = zombies.value.filter(zombie => {
    if (zombie.health <= 0) return false // 立即移除死亡僵尸
    
    const deltaX = playerX.value - zombie.x
    const deltaY = playerY.value - zombie.y
    const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY)
    
    if (distance > 5) { // 添加最小移动阈值，避免微小抖动
      // 添加平滑移动，避免抽搐
      const moveSpeed = Math.min(zombie.speed, distance * 0.1) // 根据距离调整速度
      const targetX = zombie.x + (deltaX / distance) * moveSpeed
      const targetY = zombie.y + (deltaY / distance) * moveSpeed
      
      // 使用平滑插值，减少抖动
      zombie.x += (targetX - zombie.x) * 0.2
      zombie.y += (targetY - zombie.y) * 0.2
    }
    
    // 检查是否攻击玩家（基于实际尺寸的真实碰撞检测）
      // 僵尸和玩家都是30x30，真实碰撞距离应为15+15=30像素中心距离
      if (distance < 25) {
        playerHealth.value -= 1
        
        if (playerHealth.value <= 0) {
          gameOver.value = true
        }
      }
    return true
  })
  
  // 更新道具（移除过期道具）
  items.value = items.value.filter(item => {
    // 移除超过存在时间的道具
    if (Date.now() - item.createdAt > config.itemLifetime) {
      return false
    }
    
    // 检查玩家拾取
      const distance = Math.sqrt(
        Math.pow(playerX.value + 15 - item.x, 2) + 
        Math.pow(playerY.value + 15 - item.y, 2)
      )
      
      if (distance < 25) {
        // 拾取道具
        if (item.type === 'health') {
          playerHealth.value = Math.min(100, playerHealth.value + 30)
        } else if (item.type === 'ammo') {
          ammo.value = Math.min(maxAmmo.value, ammo.value + 15)
        } else if (item.type === 'weapon') {
          // 切换武器
          currentWeapon.value = item.weaponType
          ammo.value = weapons[item.weaponType].ammo
          maxAmmo.value = weapons[item.weaponType].maxAmmo
        }
        return false // 移除已拾取的道具
      }
    
    return true
  })

  // 检查波次完成
  if (zombies.value.every(zombie => zombie.health <= 0)) {
    if (!waveComplete.value) {
      waveComplete.value = true
      setTimeout(() => {
        if (currentWave.value < 5) {
          currentWave.value++
          startWave()
        } else {
          // 完成5个波次，游戏胜利
          gameOver.value = true
        }
      }, 3000)
    }
  }
}

// 暂停/恢复游戏
const togglePause = () => {
  if (!gameStarted.value || gameOver.value) return
  isPaused.value = !isPaused.value
}

// 键盘控制
const keysPressed = new Set()

const handleKeyDown = (event) => {
  if (!gameStarted.value || gameOver.value) return
  
  const key = event.key.toLowerCase()
  keysPressed.add(key)
  
  if (key === 'r') reload()
  if (key === '1') switchWeapon('pistol')
  if (key === '2') switchWeapon('shotgun')
  if (key === '3') switchWeapon('rifle')
  if (key === 'p') togglePause()
}

const handleKeyUp = (event) => {
  if (!gameStarted.value || gameOver.value) return
  
  const key = event.key.toLowerCase()
  keysPressed.delete(key)
}

onMounted(() => {
  window.addEventListener('keydown', handleKeyDown)
  window.addEventListener('keyup', handleKeyUp)
})

onUnmounted(() => {
  window.removeEventListener('keydown', handleKeyDown)
  window.removeEventListener('keyup', handleKeyUp)
  if (gameLoop) clearInterval(gameLoop)
  if (zombieSpawnTimer) clearInterval(zombieSpawnTimer)
})
</script>

<style scoped>
.game-container {
  max-width: 1100px;
  margin: 0 auto;
  padding: 20px;
  background: linear-gradient(135deg, #1a1a2e, #16213e);
  color: white;
  border-radius: 10px;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
  min-width: 1100px;
}

.game-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding: 15px;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 8px;
}

.game-header h1 {
  margin: 0;
  color: #ff6b6b;
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}

.game-stats {
  display: flex;
  gap: 20px;
}

.stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
}

.health-bar {
  width: 100px;
  height: 10px;
  background: #333;
  border-radius: 5px;
  overflow: hidden;
}

.health-fill {
  height: 100%;
  background: linear-gradient(90deg, #ff6b6b, #ff8e8e);
  transition: width 0.3s ease;
}

.score, .wave, .ammo {
  font-weight: bold;
  color: #ffd93d;
}

.game-area {
  position: relative;
  width: 1000px;
  height: 750px;
  background: linear-gradient(135deg, #1e3c72, #2a5298);
  border: 2px solid #333;
  border-radius: 10px;
  overflow: hidden;
  cursor: crosshair;
  transition: background 1s ease;
}

.wave-1 {
  background: linear-gradient(135deg, #1e3c72, #2a5298);
}

.wave-2 {
  background: linear-gradient(135deg, #2d5016, #4a7c59);
}

.wave-3 {
  background: linear-gradient(135deg, #8b4513, #cd853f);
}

.wave-4 {
  background: linear-gradient(135deg, #4b0082, #8a2be2);
}

.wave-5 {
  background: linear-gradient(135deg, #8b0000, #ff4500);
}

.player {
  position: absolute;
  width: 40px;
  height: 40px;
  transform: translate(-50%, -50%);
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
}

.player-icon {
  font-size: 32px;
}

.gun {
  position: absolute;
  width: 30px;
  height: 4px;
  background: #333;
  top: 50%;
  right: -15px;
  transform-origin: left center;
  border-radius: 2px;
  box-shadow: 0 0 4px rgba(0,0,0,0.5);
  transition: transform 0.1s ease;
}

.zombie {
  position: absolute;
  width: 28px;
  height: 28px;
  background: #4a4a4a;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  transition: all 0.3s ease;
  box-shadow: 0 2px 6px rgba(0,0,0,0.3);
}

.zombie-type-2 {
  background: linear-gradient(135deg, #8b0000, #ff4500);
  box-shadow: 0 2px 12px rgba(255, 69, 0, 0.5);
}

.zombie-type-3 {
  background: linear-gradient(135deg, #4b0082, #8a2be2);
  box-shadow: 0 2px 15px rgba(138, 43, 226, 0.6);
}

.zombie-icon {
  font-size: 24px;
  display: block;
  text-align: center;
  animation: zombieWalk 1s infinite alternate;
}

@keyframes zombieWalk {
  0% { transform: translateX(-2px); }
  100% { transform: translateX(2px); }
}

.zombie-dead {
  opacity: 0.3;
  transform: rotate(90deg);
}

.zombie-health {
  position: absolute;
  top: -8px;
  left: 0;
  width: 30px;
  height: 3px;
  background: #333;
  border-radius: 2px;
}

.zombie-health-bar {
  height: 100%;
  background: #ff6b6b;
  transition: width 0.3s ease;
}

.bullet {
  position: absolute;
  width: 6px;
  height: 6px;
  background: #ffd93d;
  border-radius: 50%;
  z-index: 5;
}

.item {
  position: absolute;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  z-index: 8;
  animation: pulse 1.5s infinite;
  box-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
}

.item.health {
  background: linear-gradient(135deg, #ff6b6b, #ff8e8e);
}

.item.ammo {
  background: linear-gradient(135deg, #4a90e2, #6bb6ff);
}

@keyframes pulse {
  0% { transform: scale(1); }
  50% { transform: scale(1.1); }
  100% { transform: scale(1); }
}

.game-over, .wave-complete {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: rgba(0, 0, 0, 0.8);
  color: white;
  padding: 40px;
  border-radius: 10px;
  text-align: center;
  z-index: 100;
}

.restart-btn, .start-btn, .reload-btn {
  background: linear-gradient(135deg, #ff6b6b, #ff8e8e);
  color: white;
  border: none;
  padding: 12px 24px;
  border-radius: 5px;
  cursor: pointer;
  font-size: 16px;
  margin: 5px;
  transition: transform 0.2s ease;
}

.restart-btn:hover, .start-btn:hover, .reload-btn:hover:not(:disabled) {
  transform: translateY(-2px);
}

.reload-btn:disabled {
  background: #666;
  cursor: not-allowed;
}

.controls {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-top: 20px;
}

.instructions {
  margin-top: 20px;
  padding: 15px;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 8px;
}

.instructions h3 {
  margin-top: 0;
  color: #ffd93d;
}

.instructions p {
  margin: 5px 0;
  font-size: 14px;
}

/* 全局居中样式 */
body {
  margin: 0;
  padding: 0;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0a0a0a;
}

#app {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
}
</style>
